import { useCallback, useEffect, useRef, useState } from 'react'
import { chatAPI } from '../services/api'

declare global {
  interface Window {
    webkitSpeechRecognition?: any
    SpeechRecognition?: any
  }
}

export function useSpeechInput() {
  const [recording, setRecording] = useState(false)
  const [transcribing, setTranscribing] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [supported, setSupported] = useState(false)
  const mediaRecorderRef = useRef<MediaRecorder | null>(null)
  const chunksRef = useRef<Blob[]>([])

  useEffect(() => {
    setSupported('mediaDevices' in navigator)
  }, [])

  const start = useCallback(async () => {
    setError(null)
    if (!navigator.mediaDevices?.getUserMedia) {
      setError('该设备不支持麦克风录音')
      return
    }
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
      const recorder = new MediaRecorder(stream)
      mediaRecorderRef.current = recorder
      chunksRef.current = []

      recorder.ondataavailable = (e) => {
        if (e.data && e.data.size > 0) chunksRef.current.push(e.data)
      }
      recorder.onstop = () => {
        // no-op
      }
      recorder.start(100)
      setRecording(true)
    } catch (e: any) {
      setError(e?.message || '无法访问麦克风')
    }
  }, [])

  const stopAndTranscribe = useCallback(async (): Promise<string | null> => {
    if (!mediaRecorderRef.current) return null
    const recorder = mediaRecorderRef.current
    if (recorder.state !== 'inactive') recorder.stop()
    setRecording(false)

    const blob = new Blob(chunksRef.current, { type: 'audio/webm' })
    chunksRef.current = []

    // 转 base64
    const toBase64 = (b: Blob) => new Promise<string>((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = () => resolve(String(reader.result))
      reader.onerror = reject
      reader.readAsDataURL(b)
    })

    try {
      setTranscribing(true)
      const base64 = await toBase64(blob)
      const result = await chatAPI.transcribeAudio(base64, blob.type)
      setTranscribing(false)
      if (result.success && result.text) return result.text
      setError(result.error || '转写失败')
      return null
    } catch (e: any) {
      setTranscribing(false)
      setError(e?.message || '转写请求失败')
      return null
    }
  }, [])

  const cancel = useCallback(() => {
    if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
      mediaRecorderRef.current.stop()
    }
    chunksRef.current = []
    setRecording(false)
    setTranscribing(false)
  }, [])

  return { supported, recording, transcribing, error, start, stopAndTranscribe, cancel }
}


